﻿namespace MvcScriptManager.UniqueKeyEncoding
{
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Web;

    /// <summary>
    /// Class to handle creating unique keys for ScriptManager files by using a one-way hash
    /// based on the URL of the file. Uses a local cache to store/retrieve ScriptReference details
    /// based on the hash
    /// </summary>
    public class UniqueKeyOneWayHash : IUniqueKeyEncoder
    {
        private static readonly Dictionary<string, ScriptReference> ScriptMapping = new Dictionary<string, ScriptReference>();

        /// <summary>
        /// Creates the unique key from the ScriptReference
        /// </summary>
        /// <param name="reference">The <see cref="ScriptReference"/></param>
        /// <param name="context">The HttpContext for the current request</param>
        /// <returns>The unique key for the file</returns>
        public string EncodeUniqueKey(ScriptReference reference, HttpContext context)
        {
            string uniqueKey = reference.GetUrl(context, true).GetHashCode().ToString("x", CultureInfo.InvariantCulture);

            if (!ScriptMapping.ContainsKey(uniqueKey))
            {
                ScriptMapping.Add(uniqueKey, reference);
            }

            return uniqueKey;
        }

        /// <summary>
        /// Rebuilds the ScriptReference object from a unique key
        /// </summary>
        /// <param name="uniqueKey">The unique key for the file</param>
        /// <param name="context">The HttpContext for the current request</param>
        /// <returns>The <see cref="ScriptReference"/></returns>
        public ScriptReference DecodeUniqueKey(string uniqueKey, HttpContext context)
        {
            if (!ScriptMapping.ContainsKey(uniqueKey))
            {
                // Fail fast
                throw new InvalidOperationException(
                        string.Format(CultureInfo.InvariantCulture, "MvcScriptManager unique key '{0}' doesn't exist in local cache.", uniqueKey));
            }

            return ScriptMapping[uniqueKey];
        }
    }
}
